package com.cloudkinto.common;

import cn.hutool.core.collection.CollUtil;
import com.cloudkinto.dto.print.common.DynamicTableDto;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.policy.DynamicTableRenderPolicy;
import com.deepoove.poi.policy.TableRenderPolicy;
import com.deepoove.poi.util.TableTools;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;

import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author long
 * @Description 行合并的动态表格渲染策略
 * @Date 2024/12/14 9:38
 */
public class DynamicTablePolicy extends DynamicTableRenderPolicy {
    @Override
    public void render(XWPFTable table, Object tableData) throws Exception {
        this.setTable(table);
        if (Objects.isNull(tableData)) {
            return;
        }
        // 参数数据声明
        DynamicTableDto dynamicTableDto = (DynamicTableDto) tableData;
        List<RowRenderData> dataList = dynamicTableDto.getDataList();
        Map<String, Integer> groupMap = dynamicTableDto.getGroupMap();
        Integer mergeIndex = dynamicTableDto.getMergeIndex();
        Integer columnCount = dynamicTableDto.getTableCol();
        Integer tableHeaderRowCount = dynamicTableDto.getTableHeaderRowCount();
        Integer mergeColFrom = dynamicTableDto.getMergeColFrom();
        Integer mergeColTo = dynamicTableDto.getMergeColNum();

        if (CollUtil.isNotEmpty(dataList)) {
            table.removeRow(tableHeaderRowCount);
            // 行从中间插入, 因此采用倒序渲染数据
            for (int i = dataList.size() - 1; i >= 0; i--) {
                XWPFTableRow newRow = table.insertNewTableRow(tableHeaderRowCount);
                newRow.setHeight(400);
                for (int j = 0; j < columnCount; j++) {
                    newRow.createCell();
                }
                // 渲染一行数据
                TableRenderPolicy.Helper.renderRow(newRow, dataList.get(i));
            }
            // 处理合并
            for (int i = 0; i < dataList.size(); i++) {
                // 获取要合并的名称那一列数据
                String typeNameData = dataList.get(i).getCells().get(mergeIndex).getParagraphs().get(0).getContents().get(0).toString();
                Integer rowNum = groupMap.get(typeNameData);
                if (Objects.nonNull(rowNum)) {
                    if (rowNum == 1) {
                        //只有一行数据不用合并
                        continue;
                    }
                    for (int k = mergeColFrom; k < mergeColTo; k++) {
                        TableTools.mergeCellsVertically(table, k, tableHeaderRowCount + i, tableHeaderRowCount - 1 + i + rowNum);
                    }
                    i = i + rowNum - 1;
                }
            }
        }
    }

    /**
     * 单元格加边框
     */
    private void setTable(XWPFTable table) {
        CTTblBorders borders = table.getCTTbl().getTblPr().addNewTblBorders();
        CTBorder hBorder = borders.addNewInsideH();
        // 线条类型
        hBorder.setVal(STBorder.Enum.forString("single"));
        // 线条大小
        hBorder.setSz(new BigInteger("1"));
        // 设置颜色
        hBorder.setColor("000000");

        CTBorder vBorder = borders.addNewInsideV();
        vBorder.setVal(STBorder.Enum.forString("single"));
        vBorder.setSz(new BigInteger("1"));
        vBorder.setColor("000000");

        CTBorder lBorder = borders.addNewLeft();
        lBorder.setVal(STBorder.Enum.forString("single"));
        lBorder.setSz(new BigInteger("1"));
        lBorder.setColor("000000");

        CTBorder rBorder = borders.addNewRight();
        rBorder.setVal(STBorder.Enum.forString("single"));
        rBorder.setSz(new BigInteger("1"));
        rBorder.setColor("000000");

        CTBorder tBorder = borders.addNewTop();
        tBorder.setVal(STBorder.Enum.forString("single"));
        tBorder.setSz(new BigInteger("1"));
        tBorder.setColor("000000");

        CTBorder bBorder = borders.addNewBottom();
        bBorder.setVal(STBorder.Enum.forString("single"));
        bBorder.setSz(new BigInteger("1"));
        bBorder.setColor("000000");
    }
}